module nkf;

private
{

extern (C)
{

string dnkf_version();

string dnkf_convert(const(char) *optStr, 
                    size_t optLen, 
                    const(char) *inStr, 
                    size_t inLen);

string dnkf_guess(const(char) *inStr, 
                  size_t inLen);

void dnkf_module_ctor();

void dnkf_module_dtor();

} // extern (C)

shared(Object) _lock;

} // private

shared static this ()
{
    _lock = new shared(Object);
    dnkf_module_ctor();
}

shared static ~this ()
{
    dnkf_module_dtor();
}


/**
 * NKF の内部エラー
 */
class NkfException: Exception
{
    this (string msg)
    {
        super (msg);
    }
}


enum Guess: string
{
    UNKNOWN = "",
    
    JIS    = "ISO-2022-JP",
    BINARY = "BINARY",
    ASCII  = "ASCII",
    SJIS   = "Shift_JIS",
    EUC    = "EUC-JP",
    UTF8   = "UTF-8",
    UTF16  = "UTF-16",
    UTF32  = "UTF-32",
}


/**
 * このポーティングのバージョン 
 */
enum string VERSION = "1.0.0";

/**
 * 使用しているNKFのバージョン
 */
string nkfVersion()
{
    return dnkf_version();
}


/**
 * 文字列の文字コード変換を行う
 * 
 * Params:
 *   options = NKFのオプションスイッチ。詳細は nkf (1) を参照。
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
string nkf(const(char)[] option, const(char)[] source)
{
    synchronized (_lock)
    {
        return dnkf_convert(option.ptr, option.length, 
                            source.ptr, source.length);
    }
}


/**
 * 文字列の文字コードを自動判別する。
 * 
 * Params:
 *   source = 文字コード自動判別の対象となる文字列
 * 
 * Returns:
 *   自動判別した文字コード
 */
Guess guess(const(char)[] source)
{
    synchronized (_lock)
    {
        return cast(Guess)dnkf_guess(source.ptr, source.length);
    }
}


/**
 * 文字列の文字コードを Shift_JIS に変換する
 * 
 * Params:
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
string toSJIS(const(char)[] source)
{
    return nkf("-s", source);
}

/**
 * 文字列の文字コードを JIS に変換する
 * 
 * Params:
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
string toJIS(const(char)[] source)
{
    return nkf("-j", source);
}

/**
 * 文字列の文字コードを EUC-JP に変換する
 * 
 * Params:
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
string toEUC(const(char)[] source)
{
    return nkf("-e", source);
}

/**
 * 文字列の文字コードをシステムの文字コードに変換する
 * 
 * Params:
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
string toSys(const(char)[] source)
{
    return nkf("", source);
}

/**
 * 文字列の文字コードを UTF-8 に変換する
 * 
 * Params:
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
string toUTF8(const(char)[] source)
{
    return nkf("-w80", source);
}

/**
 * 文字列の文字コードを UTF-16 に変換する
 * 
 * Params:
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
wstring toUTF16(const(char)[] source)
{
    return cast(wstring)nkf("-w16", source);
}

/**
 * 文字列の文字コードを UTF-32 に変換する
 * 
 * Params:
 *   source = 文字コード変換の対象となる文字列
 * 
 * Returns:
 *   文字コード変換された文字列
 * 
 * Throws:
 *   内部エラー, NkfException
 */
dstring toUTF32(const(char)[] source)
{
    return cast(dstring)nkf("-w32", source);
}


